//
//  UIViewExtensions.swift
//  Fangxukanghan
//
//  Created by 常超群的MacBookPro on 2021/3/22.
//

import Foundation
import SwifterSwift
/// 给view增加点击事件
public extension UIView {
    func ccq_tapGestureHandler(closure: @escaping CCQVoidClosure) {
        targetClosure = closure
        let gestureReconizer = UITapGestureRecognizer(target: self, action: #selector(UIView.tapClosureAction))
        isUserInteractionEnabled = true
        addGestureRecognizer(gestureReconizer)
    }
    private struct AssociatedKeys { static var targetClosure = "targetClosure" }
    private class ClosureWrapper: NSObject {
        let closure: CCQVoidClosure
        init(_ closure: @escaping CCQVoidClosure) { self.closure = closure }
    }
    @objc private func tapClosureAction() { targetClosure?() }
    private var targetClosure: CCQVoidClosure? {
        get { return (objc_getAssociatedObject(self, &AssociatedKeys.targetClosure) as? ClosureWrapper)?.closure }
        set {
            guard let newValue = newValue else { return }
            objc_setAssociatedObject(self, &AssociatedKeys.targetClosure, ClosureWrapper(newValue), objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
}
/// 给view增加可以箭头
public extension UIView {
    enum CCQArrowDirection {
        case left
        case top
        case right
        case bottom
    }
    
    /// 给view增加箭头
    /// - Parameters:
    ///   - point: 箭头位置(如果为上)
    ///   - arrowDirection: 方向
    ///   - strokeColor: 线条颜色
    ///   - fillColor: 填充色
    func ccq_setArrowDirectionWith(point: CGPoint, arrowDirection: CCQArrowDirection, strokeColor: UIColor, fillColor: UIColor) {
        var startPoint = CGPoint.zero
        var middlePoint = CGPoint.zero
        var endPoint = CGPoint.zero
        // 线的路径
        let polygonPath = UIBezierPath()
        switch arrowDirection {
        case .left:
            startPoint = CGPoint(x: point.x, y: point.y + 7);
            middlePoint = CGPoint(x: point.x - 7, y: point.y);
            endPoint = CGPoint(x: point.x, y: point.y - 7);
            // 起点
            polygonPath.move(to: CGPoint(x: 5, y: 0))
            
            polygonPath.addLine(to: CGPoint(x: width - 5, y: 0))
            polygonPath.addCurve(to: CGPoint(x: width, y: 5), controlPoint1: CGPoint(x: width - 5, y: 0), controlPoint2: CGPoint(x: width, y: 0))
            
            polygonPath.addLine(to: CGPoint(x: width, y: height - 5))
            polygonPath.addCurve(to: CGPoint(x: width - 5, y: height), controlPoint1: CGPoint(x: width, y: height - 5), controlPoint2: CGPoint(x: width, y: height))
            
            polygonPath.addLine(to: CGPoint(x: 5, y: height))
            polygonPath.addCurve(to: CGPoint(x: 0, y: height - 5), controlPoint1: CGPoint(x: 5, y: height), controlPoint2: CGPoint(x: 0, y: height))
            
            polygonPath.addLine(to: startPoint)
            polygonPath.addLine(to: middlePoint)
            polygonPath.addLine(to: endPoint)

            polygonPath.addLine(to: CGPoint(x: 0, y: 5))
            polygonPath.addCurve(to: CGPoint(x: 5, y: 0), controlPoint1: CGPoint(x: 0, y: 5), controlPoint2: CGPoint(x: 0, y: 0))

        case .top:
            startPoint = CGPoint(x: point.x - 7, y: point.y);
            middlePoint = CGPoint(x: point.x, y: point.y - 7);
            endPoint = CGPoint(x: point.x + 7, y: point.y);
            // 起点
            polygonPath.move(to: CGPoint(x: 5, y: 0))
            
            polygonPath.addLine(to: startPoint)
            polygonPath.addLine(to: middlePoint)
            polygonPath.addLine(to: endPoint)
            
            polygonPath.addLine(to: CGPoint(x: width - 5, y: 0))
            polygonPath.addCurve(to: CGPoint(x: width, y: 5), controlPoint1: CGPoint(x: width - 5, y: 0), controlPoint2: CGPoint(x: width, y: 0))
            
            polygonPath.addLine(to: CGPoint(x: width, y: height - 5))
            polygonPath.addCurve(to: CGPoint(x: width - 5, y: height), controlPoint1: CGPoint(x: width, y: height - 5), controlPoint2: CGPoint(x: width, y: height))
            
            polygonPath.addLine(to: CGPoint(x: 5, y: height))
            polygonPath.addCurve(to: CGPoint(x: 0, y: height - 5), controlPoint1: CGPoint(x: 5, y: height), controlPoint2: CGPoint(x: 0, y: height))

            polygonPath.addLine(to: CGPoint(x: 0, y: 5))
            polygonPath.addCurve(to: CGPoint(x: 5, y: 0), controlPoint1: CGPoint(x: 0, y: 5), controlPoint2: CGPoint(x: 0, y: 0))
        case .right:
            startPoint = CGPoint(x: point.x, y: point.y - 7);
            middlePoint = CGPoint(x: point.x + 7, y: point.y);
            endPoint = CGPoint(x: point.x, y: point.y + 7);
            // 起点
            polygonPath.move(to: CGPoint(x: 5, y: 0))
            
            polygonPath.addLine(to: CGPoint(x: width - 5, y: 0))
            polygonPath.addCurve(to: CGPoint(x: width, y: 5), controlPoint1: CGPoint(x: width - 5, y: 0), controlPoint2: CGPoint(x: width, y: 0))
            
            polygonPath.addLine(to: startPoint)
            polygonPath.addLine(to: middlePoint)
            polygonPath.addLine(to: endPoint)
            
            polygonPath.addLine(to: CGPoint(x: width, y: height - 5))
            polygonPath.addCurve(to: CGPoint(x: width - 5, y: height), controlPoint1: CGPoint(x: width, y: height - 5), controlPoint2: CGPoint(x: width, y: height))
            
            polygonPath.addLine(to: CGPoint(x: 5, y: height))
            polygonPath.addCurve(to: CGPoint(x: 0, y: height - 5), controlPoint1: CGPoint(x: 5, y: height), controlPoint2: CGPoint(x: 0, y: height))

            polygonPath.addLine(to: CGPoint(x: 0, y: 5))
            polygonPath.addCurve(to: CGPoint(x: 5, y: 0), controlPoint1: CGPoint(x: 0, y: 5), controlPoint2: CGPoint(x: 0, y: 0))
        case .bottom:
            startPoint = CGPoint(x: point.x + 7, y: point.y);
            middlePoint = CGPoint(x: point.x, y: point.y + 7);
            endPoint = CGPoint(x: point.x - 7, y: point.y);
            // 起点
            polygonPath.move(to: CGPoint(x: 5, y: 0))
            
            polygonPath.addLine(to: CGPoint(x: width - 5, y: 0))
            polygonPath.addCurve(to: CGPoint(x: width, y: 5), controlPoint1: CGPoint(x: width - 5, y: 0), controlPoint2: CGPoint(x: width, y: 0))
            
            polygonPath.addLine(to: CGPoint(x: width, y: height - 5))
            polygonPath.addCurve(to: CGPoint(x: width - 5, y: height), controlPoint1: CGPoint(x: width, y: height - 5), controlPoint2: CGPoint(x: width, y: height))
            
            polygonPath.addLine(to: startPoint)
            polygonPath.addLine(to: middlePoint)
            polygonPath.addLine(to: endPoint)
            
            polygonPath.addLine(to: CGPoint(x: 5, y: height))
            polygonPath.addCurve(to: CGPoint(x: 0, y: height - 5), controlPoint1: CGPoint(x: 5, y: height), controlPoint2: CGPoint(x: 0, y: height))

            polygonPath.addLine(to: CGPoint(x: 0, y: 5))
            polygonPath.addCurve(to: CGPoint(x: 5, y: 0), controlPoint1: CGPoint(x: 0, y: 5), controlPoint2: CGPoint(x: 0, y: 0))
        }
        
        let polygonLayer = CAShapeLayer()
        polygonLayer.lineWidth = 1
        //线颜色
        polygonLayer.strokeColor = strokeColor.cgColor
        polygonLayer.path = polygonPath.cgPath
        //填充颜色
        polygonLayer.fillColor = fillColor.cgColor
        self.layer.addSublayer(polygonLayer)
    }
}
/// 给view增加阴影
public extension UIView {
    enum CCQShadowDirection {
        case left
        case top
        case right
        case bottom
        case leftAndRightAndBottom
        case all
    }
    
    /// 给view增加阴影
    /// - Parameters:
    ///   - shadowColor: 阴影颜色
    ///   - shadowOpacity: 阴影透明度
    ///   - shadowRadius: 阴影半径
    ///   - shadowWidth: 阴影宽度
    ///   - shadowDirection: 阴影位置（上下左右）
    func ccq_addShadowPathWith(shadowColor: UIColor = UIColor(red: 0.07, green: 0.47, blue: 0.57, alpha: 1.0), shadowOpacity: CGFloat = 0, shadowRadius: CGFloat = 3, shadowWidth: CGFloat = 3, shadowDirection: CCQShadowDirection = .all) {
        self.layer.masksToBounds = false;//必须要等于NO否则会把阴影切割隐藏掉
        self.layer.shadowColor = shadowColor.cgColor;// 阴影颜色
        self.layer.shadowOpacity = Float(shadowOpacity);// 阴影透明度，默认0
        self.layer.shadowOffset = CGSize.zero;//shadowOffset阴影偏移，默认(0, -3),这个跟shadowRadius配合使用
        self.layer.shadowRadius = shadowRadius;//阴影半径，默认3
        var shadowRect = CGRect.zero;
        
        let originX: CGFloat = 0
        let originY: CGFloat = 0
        let sizeWith: CGFloat = self.bounds.size.width
        let sizeHeight: CGFloat = self.bounds.size.height
        if (shadowDirection == .top) {
            shadowRect = CGRect(x: originX, y: originY-shadowWidth/2, width: sizeWith, height: shadowWidth)
        } else if (shadowDirection == .bottom) {
            shadowRect = CGRect(x: originY, y: sizeHeight-shadowWidth/2, width: sizeWith, height: shadowWidth)
        } else if (shadowDirection == .left) {
            shadowRect = CGRect(x: originX-shadowWidth/2, y: originY, width: shadowWidth, height: sizeHeight)
        } else if (shadowDirection == .right) {
            shadowRect = CGRect(x: sizeWith-shadowWidth/2, y: originY, width: shadowWidth, height: sizeHeight)
        } else if (shadowDirection == .leftAndRightAndBottom) {
            shadowRect = CGRect(x: originX-shadowWidth/2, y: 2, width: sizeWith+shadowWidth, height: sizeHeight+shadowWidth/2)
        } else if (shadowDirection == .all) {
            shadowRect = CGRect(x: originX-shadowWidth/2, y: originY-shadowWidth/2, width: sizeWith+shadowWidth, height: sizeHeight+shadowWidth)
        }
        let bezierPath = UIBezierPath(rect: shadowRect)
        self.layer.shadowPath = bezierPath.cgPath;//阴影路径
    }
}
/// 给view添加边框
public extension UIView {
    func ccq_setBorderWith(left: Bool = false, top: Bool = false, right: Bool = false, bottom: Bool = false, borderColor: UIColor = .red, borderWidth: CGFloat = 0.5) {
        if top {
            let layer = CALayer()
            layer.frame = CGRect(x: 0, y: 0, width: self.width, height: borderWidth)
            layer.backgroundColor = borderColor.cgColor
            self.layer.addSublayer(layer)
        }
        if left {
            let layer = CALayer()
            layer.frame = CGRect(x: 0, y: 0, width: borderWidth, height: self.height)
            layer.backgroundColor = borderColor.cgColor
            self.layer.addSublayer(layer)
        }
        if bottom {
            let layer = CALayer()
            layer.frame = CGRect(x: 0, y: self.height - borderWidth, width: self.width, height: borderWidth)
            layer.backgroundColor = borderColor.cgColor
            self.layer.addSublayer(layer)
        }
        if right {
            let layer = CALayer()
            layer.frame = CGRect(x: self.width - borderWidth, y: 0, width: borderWidth, height: self.height)
            layer.backgroundColor = borderColor.cgColor
            self.layer.addSublayer(layer)
        }
    }
}
/// 获取view所在的vc
public extension UIView {
    /// 获取view所在的vc
    func ccq_getFirstViewController() -> UIViewController? {
        for view in sequence(first: self.superview, next: {$0?.superview}) {
            if let responder = view?.next {
                if responder.isKind(of: UIViewController.self){
                    return responder as? UIViewController
                }
            }
        }
        return nil
    }
}
/// view 添加渐变色
public extension UIView {
    
    func ccq_generateGradientLayer(_ colorFrom: UIColor = .red, _ colorTo: UIColor = .yellow, frame: CGRect? = nil) -> CAGradientLayer {
        return ccq_generateGradientLayer(CGPoint(x: 0, y: 0.5), CGPoint(x: 1, y: 0.5), colorFrom, colorTo, frame: frame)
    }
    func ccq_generateGradientLayer(_ startPoint: CGPoint = CGPoint(x: 0, y: 0.5), _ endPoint: CGPoint = CGPoint(x: 1, y: 0.5), _ colorFrom: UIColor = .red, _ colorTo: UIColor = .yellow, frame: CGRect? = nil) -> CAGradientLayer {
        let gradientLayer = CAGradientLayer()
        // ⚠️ 如果在 Controler 的 viewDidLoad() 方法中调用，很可能bounds的宽高为0
        if let frame = frame {
            gradientLayer.frame = frame
        } else {
            gradientLayer.frame = bounds
        }
        
        //  创建渐变色数组，需要转换为CGColor颜色
        gradientLayer.colors = [colorFrom.cgColor, colorTo.cgColor]
        
        //  设置渐变颜色方向，左上点为(0,0), 右下点为(1,1)
        gradientLayer.startPoint = startPoint
        gradientLayer.endPoint = endPoint
        
        //  设置颜色变化点，取值范围 0.0~1.0
        gradientLayer.locations = [NSNumber(value: 0),NSNumber(value: 1)];
        
        return gradientLayer
    }
}
